method DYNASTIE constructor {} {
	#format [list ID [List INDIVIDU] [List ID] [list ID]] : [ref [cibles+] [peres+] [fils+]]
	set this(L_individu) ""	
	set this(next_id) 0
}

#Add individu.
#params : new {}, individu is related to nobody (ie. created by a start}
#params : copy i, individu is equivalent to individu ie
#params : mutations i
#params : mating i j 
method DYNASTIE add_individu {individu {params  {new {}}}} {
	lassign $params relation i j 

	switch -- $relation {
		copy { 
			set indx [lsearch -regexp -index 1 $this(L_individu) ".*\\y${i}\\y.*"] 
			if {$indx < 0} { 
				puts stderr "Invalid Copy : $i is Unregistred" 
				lappend this(L_individu) [list [this next_ID] [list $individu] [list] [list]]
			}
			lassign [lindex $this(L_individu) $indx] ID L_indiv L_peres L_fils
			set this(L_individu) [lreplace $this(L_individu) $indx $indx [list $ID [concat $L_indiv $individu] $L_peres $L_fils]]
		}
		mutation -
		mating -
		new {
			
			set new_id [this next_ID] 
			if {$i != {}} {set indx_i [lsearch -regexp -index 1 $this(L_individu) ".*\\y${i}\\y.*"]} {set indx_i -1} 
			if {$j != {}} {set indx_j [lsearch -regexp -index 1 $this(L_individu) ".*\\y${j}\\y.*"]} {set indx_j -1} 
			
			set id_i ""
			set id_j ""
			if {$indx_i != -1} {
				lassign [lindex $this(L_individu) $indx_i] id_i indiv_i lp_i lf_i 
				set this(L_individu) [lreplace $this(L_individu) $indx_i $indx_i [list $id_i $indiv_i $lp_i [lsort -uniq [concat $lf_i $new_id]]]]
			}			
			if {$indx_j != -1} {
				lassign [lindex $this(L_individu) $indx_j] id_j indiv_j lp_j lf_j 
				set this(L_individu) [lreplace $this(L_individu) $indx_j $indx_j [list $id_j $indiv_j $lp_j [lsort -uniq [concat $lf_j $new_id]]]]
			}
			
			lappend this(L_individu) [list $new_id [list $individu] [lsort -uniq [list $id_i $id_j]] [list]]
			
			
		}
	}
	
}

method DYNASTIE next_ID {} {
	incr this(next_id) 
	return $this(next_id)
}

method DYNASTIE toDot {individu } {
	set this(done) "" 
	set this(file) [open ${individu}.dot w]
	set blob [lsearch -regexp -index 1 -inline $this(L_individu) ".*\\y${individu}\\y.*"]
	if {$blob == ""} {
		puts stderr "Error : INDIVIDU $individu unregistred"
		return 
	}		
		set scale 2
	lassign $blob id L_individu L_pere L_fils	
	set this(graphHandle) [dotnew digraph] 
	puts $this(file) "digraph $individu  {" 
		
		lappend this(done) $id 
		set myNode [$this(graphHandle) addnode $id ]
		$myNode setattributes label "$id : [lindex $blob 1] "
		$myNode setattributes shape "hexagon"
		puts $this(file) "$myNode \[label=\"$id : [lindex [lindex $blob 1] 0]\",shape=\"hexagon\"\];"
		this recursiveToDot up $myNode $blob
		this recursiveToDot down $myNode $blob
	puts $this(file) "}"
	close $this(file)

	if [catch {canvas .canvasGraph_$objName} ] {}
	pack .canvasGraph_$objName -expand 1 -fill both
	set c .canvasGraph_$objName
	eval [$this(graphHandle)  render]

	return $this(graphHandle) 

}
method DYNASTIE get_html {individu} {
	this toDot $individu
	
	exec dot -T dot ${individu}.dot  > temp.dot 
	exec dot -T gif ${individu}.dot  > individu/img/${individu}.gif

	set this(graphHandle) [dotread [open temp.dot]]
	set file [open individu/${individu}.html w]
		lassign [split [$this(graphHandle) query bb] ,] a b width_graph height_graph
		puts $file "<html>\n\t<body>\n\t\t\
						<img alt=\"Graphical Representation of ${individu}'s dynasty\" \
							 src=\"./img/${individu}.gif\" 
							 width=\"[expr $scale * $width_graph]\" 
							 height=\"[expr $scale * $height_graph]\" 
							 usemap=\"#dynasty\" />"
		puts $file "<map name=\"dynasty\"> "	

		foreach node [$this(graphHandle) listnodes] {
			lassign [split [$node query pos] ,] x y 
			set x [expr int(${scale}*( $x ))]
			set y [expr int(${scale}*($height_graph - $y ))]
			set r [expr int(20*max([$node query width],[$node query width]))]
			puts $file "<area shape=\"circle\" coords=\"$x,$y,$r\" href=\"[$node query label]\" alt=\"[$node query label]\" />"
			
		}
		
	puts $file "</map>"
	puts $file "</body></html>"
	close $file
}
method DYNASTIE get_svg {individu} {
	this toDot $individu
	
	exec dot -T dot ${individu}.dot
}

method DYNASTIE recursiveToDot {direction node blob} {
	lassign $blob id L_individu L_pere L_fils
	if {$direction == "up"} { set L $L_pere} 
	if {$direction == "down"} { 
		set L $L_fils
	}
				
	foreach id $L {
		if {$id != {}} {		
			set blob [lsearch -inline -index 0 $this(L_individu) $id]
			if {[lsearch $this(done)  [lindex $blob 0] ] == -1} {
				lappend this(done) [lindex $blob 0]
				set ParentNode [$this(graphHandle) addnode [lindex $blob 0]]
				$ParentNode setattributes label "[lindex $blob 0] :  [lindex [lindex $blob 1] 0] "
				puts $this(file) "$ParentNode \[label=\"[lindex $blob 0] : [lindex [lindex $blob 1] 0]\"\];"
				if {$direction == "up"}   { 
					set edge [$this(graphHandle) addedge $ParentNode $node ]
					puts $this(file) "$ParentNode -> $node;"
				} 
				if {$direction == "down"} {
					puts "down $L_pere"
					set edge [$this(graphHandle) addedge $node $ParentNode ]	
					puts $this(file) "$node -> $ParentNode;"
				} 
				this recursiveToDot $direction $ParentNode $blob 
			} else {
				set edge [$this(graphHandle) addedge $node [lindex $blob 0]]
				foreach tmp [$this(graphHandle) listnodes] {
					if {[lsearch -regexp [$tmp query label] "^[lindex $blob 0]\\y.*"] > -1} {
						puts $this(file) "$tmp -> $node;"
					}
				}
			}


			
		}
	}
	
	#On ajoute le second pere/mere pour le mating
	if {$direction == "down"} { 		
		if {[llength $L_pere] == 2 && [lindex $L_pere 0] != {} && [lindex $L_pere 1] != {}} {
			set blob2 [lsearch -inline -index 0 $this(L_individu) [lindex $L_pere 0]]		
			if {[lsearch $this(done)  [lindex $blob2 0] ] == -1} {
				lappend this(done) [lindex $blob2 0]
				set ParentNode2 [$this(graphHandle) addnode [lindex $blob2 0] ]				
				$ParentNode2 setattributes label "[lindex $blob2 0] :  [lindex [lindex $blob2 1] 0]"
				puts $this(file) "$ParentNode2 \[label=\"[lindex $blob2 0] : [lindex [lindex $blob2 1] 0]\"\];"
				set edge [$this(graphHandle) addedge $ParentNode2 $node ]
				puts $this(file) "$ParentNode2 -> $node;"
			}
				
			set blob2 [lsearch -inline -index 0 $this(L_individu) [lindex $L_pere 1]]
			if {[lsearch $this(done)  [lindex $blob2 0] ] == -1} {
				lappend this(done) [lindex $blob2 0]
				set ParentNode2 [$this(graphHandle) addnode [lindex $blob2 0] ]
				$ParentNode2 setattributes label "[lindex $blob2 0] :  [lindex [lindex $blob2 1] 0]"
				puts $this(file) "$ParentNode2 \[label=\"[lindex $blob2 0] : [lindex [lindex $blob2 1] 0]\"\];"
				set edge [$this(graphHandle) addedge $ParentNode2 $node ]
				puts $this(file) "$ParentNode2 -> $node;"
			}
		}
	}
	return 
}

# dynasty dispose
# DYNASTIE dynasty

# dynasty add_individu i1
# dynasty add_individu i2 {mutation i1}
# dynasty add_individu i3 {copy i2}
# dynasty add_individu i4 {copy i3}
# dynasty add_individu i5 {copy i2}
# dynasty add_individu i6 {mutation i4}
# dynasty add_individu i7 {mutation i5}
# dynasty add_individu i8 {mating i6 i7}
# dynasty toDot i5 